import 'package:baselib/utils/color_base_util.dart';
import 'package:baselib/utils/px_base_util.dart';
import 'package:baselib/utils/string_base_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math' as math;
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'inkwell_button.dart';

class CommAppBar extends AppBar{

   Widget leading;
   Function defaultBack;
   Function onActionPressed;
   String actionName;
   TextStyle actionNameTextStyle;
  final bool automaticallyImplyLeading;
  Widget title;
  String titleStr;
  List<Widget> actions;
  final Widget flexibleSpace;
  final PreferredSizeWidget bottom;
  double elevation;
  Color shadowColor;
  final ShapeBorder shape;
   Color backgroundColor;
  bool isBarStatusWhite;
  final Color foregroundColor;
  @Deprecated(
    'This property is no longer used, please use systemOverlayStyle instead. '
        'This feature was deprecated after v2.4.0-0.0.pre.',
  )
  final Brightness brightness;
  final IconThemeData iconTheme;
  final IconThemeData actionsIconTheme;
  @Deprecated(
    'This property is no longer used, please use toolbarTextStyle and titleTextStyle instead. '
        'This feature was deprecated after v2.4.0-0.0.pre.',
  )
  final TextTheme textTheme;
  final bool primary;
  final bool centerTitle;
  final bool excludeHeaderSemantics;
  final double titleSpacing;
  final double toolbarOpacity;
  final double bottomOpacity;
  @override
  final Size preferredSize;
  final double toolbarHeight;
  final double leadingWidth;
  @Deprecated(
    'This property is obsolete and is false by default. '
        'This feature was deprecated after v2.4.0-0.0.pre.',
  )
  final bool backwardsCompatibility;
  final TextStyle toolbarTextStyle;
  final TextStyle titleTextStyle;
  final SystemUiOverlayStyle systemOverlayStyle;

  CommAppBar({
    Key key,
    this.leading,
    this.defaultBack,
    this.automaticallyImplyLeading = true,
    this.title,
    this.titleStr,
    this.actions,
    this.actionName,
    this.actionNameTextStyle,
    this.onActionPressed,
    this.flexibleSpace,
    this.bottom,
    this.elevation=1,
    this.shadowColor,
    this.shape,
    this.backgroundColor,
    this.isBarStatusWhite,
    this.foregroundColor,
    @Deprecated(
      'This property is no longer used, please use systemOverlayStyle instead. '
          'This feature was deprecated after v2.4.0-0.0.pre.',
    )
    this.brightness,
    this.iconTheme,
    this.actionsIconTheme,
    @Deprecated(
      'This property is no longer used, please use toolbarTextStyle and titleTextStyle instead. '
          'This feature was deprecated after v2.4.0-0.0.pre.',
    )
    this.textTheme,
    this.primary = true,
    this.centerTitle=true,
    this.excludeHeaderSemantics = false,
    this.titleSpacing,
    this.toolbarOpacity = 1.0,
    this.bottomOpacity = 1.0,
    this.toolbarHeight,
    this.leadingWidth=50,
    @Deprecated(
      'This property is obsolete and is false by default. '
          'This feature was deprecated after v2.4.0-0.0.pre.',
    )
    this.backwardsCompatibility,
    this.toolbarTextStyle,
    this.titleTextStyle,
    this.systemOverlayStyle,
  }) : assert(automaticallyImplyLeading != null),
        assert(elevation == null || elevation >= 0.0),
        assert(primary != null),
        assert(toolbarOpacity != null),
        assert(bottomOpacity != null),
        preferredSize = _PreferredAppBarSize(toolbarHeight, bottom?.preferredSize?.height),
        super(key: key){
    isBarStatusWhite=isBarStatusWhite??true;
    if(this.backgroundColor==null)this.backgroundColor = ColorBaseUtil().color_344E8E;
    if(backgroundColor==Colors.transparent){
      shadowColor=Colors.transparent;
      elevation=0;
    }
    this.title= title??Text(
      titleStr??'',
      style: TextStyle(
        fontSize: PxBaseUtil().px_18,
        color: Colors.white
      ),
    );
    this.leading=leading??InkWellButton(
      onPressed: (defaultBack==null)?(()=>Navigator.pop(Get.context)):()=>defaultBack(),
      child: Container(
          alignment: Alignment.center,
          child: Icon(
              Icons.arrow_back,
            color: (isBarStatusWhite??false)?Colors.white:Colors.black54,
          )
      ),
    );
    this.actions=actions??[
      (actionName??'').isEmpty?SizedBox(width: 0,):
      InkWellButton(
          onPressed: () => onActionPressed(),
          child: Container(
            alignment: Alignment.center,
            padding: EdgeInsets.only(
              left: PxBaseUtil().px_12,
              right: PxBaseUtil().px_12,
            ),
            child: Text(
              actionName??StringBaseUtil().Confirm,
              style: actionNameTextStyle??TextStyle(
                fontSize: PxBaseUtil().px_14,
              ),
            ),
          )),
    ];
  }

  /// Used by [Scaffold] to compute its [AppBar]'s overall height. The returned value is
  /// the same `preferredSize.height` unless [AppBar.toolbarHeight] was null and
  /// `AppBarTheme.of(context).toolbarHeight` is non-null. In that case the
  /// return value is the sum of the theme's toolbar height and the height of
  /// the app bar's [AppBar.bottom] widget.
  static double preferredHeightFor(BuildContext context, Size preferredSize) {
    if (preferredSize is _PreferredAppBarSize && preferredSize.toolbarHeight == null) {
      return (AppBarTheme.of(context).toolbarHeight ?? kToolbarHeight) + (preferredSize.bottomHeight ?? 0);
    }
    // return preferredSize.height;
    return preferredSize.height;
  }

  bool _getEffectiveCenterTitle(ThemeData theme) {
    if (centerTitle != null)
      return centerTitle;
    if (theme.appBarTheme.centerTitle != null)
      return theme.appBarTheme.centerTitle;
    assert(theme.platform != null);
    switch (theme.platform) {
      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
      case TargetPlatform.linux:
      case TargetPlatform.windows:
        return false;
      case TargetPlatform.iOS:
      case TargetPlatform.macOS:
        return actions == null || actions.length < 2;
    }
  }

  @override
  State<CommAppBar> createState() => _CommAppBarState();
}

class _CommAppBarState extends State<CommAppBar> {
  static const double _defaultElevation = 4.0;
  static const Color _defaultShadowColor = Color(0xFF000000);

  ScrollNotificationObserverState _scrollNotificationObserver;
  bool _scrolledUnder = false;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (_scrollNotificationObserver != null)
      _scrollNotificationObserver.removeListener(_handleScrollNotification);
    _scrollNotificationObserver = ScrollNotificationObserver.of(context);
    if (_scrollNotificationObserver != null)
      _scrollNotificationObserver.addListener(_handleScrollNotification);
  }

  @override
  void dispose() {
    if (_scrollNotificationObserver != null) {
      _scrollNotificationObserver.removeListener(_handleScrollNotification);
      _scrollNotificationObserver = null;
    }
    super.dispose();
  }

  void _handleDrawerButton() {
    Scaffold.of(context).openDrawer();
  }

  void _handleDrawerButtonEnd() {
    Scaffold.of(context).openEndDrawer();
  }

  void _handleScrollNotification(ScrollNotification notification) {
    if (notification is ScrollUpdateNotification) {
      final bool oldScrolledUnder = _scrolledUnder;
      _scrolledUnder = notification.depth == 0
          && notification.metrics.extentBefore > 0
          && notification.metrics.axis == Axis.vertical;
      if (_scrolledUnder != oldScrolledUnder) {
        setState(() {
          // React to a change in MaterialState.scrolledUnder
        });
      }
    }
  }

  Color _resolveColor(Set<MaterialState> states, Color widgetColor, Color themeColor, Color defaultColor) {
    return MaterialStateProperty.resolveAs<Color>(widgetColor, states)
        ?? MaterialStateProperty.resolveAs<Color>(themeColor, states)
        ?? MaterialStateProperty.resolveAs<Color>(defaultColor, states);
  }

  SystemUiOverlayStyle _systemOverlayStyleForBrightness(Brightness brightness) {
    return brightness == Brightness.dark ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark;
  }

  @override
  Widget build(BuildContext context) {
    assert(!widget.primary || debugCheckHasMediaQuery(context));
    assert(debugCheckHasMaterialLocalizations(context));
    final ThemeData theme = Theme.of(context);
    final ColorScheme colorScheme = theme.colorScheme;
    final AppBarTheme appBarTheme = AppBarTheme.of(context);
    final ScaffoldState scaffold = Scaffold.maybeOf(context);
    final ModalRoute<dynamic> parentRoute = ModalRoute.of(context);

    final FlexibleSpaceBarSettings settings = context.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
    final Set<MaterialState> states = <MaterialState>{
      if (settings?.isScrolledUnder ?? _scrolledUnder) MaterialState.scrolledUnder,
    };

    final bool hasDrawer = scaffold?.hasDrawer ?? false;
    final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false;
    final bool canPop = parentRoute?.canPop ?? false;
    final bool useCloseButton = parentRoute is PageRoute<dynamic> && parentRoute.fullscreenDialog;

    final double toolbarHeight = widget.toolbarHeight ?? appBarTheme.toolbarHeight ?? kToolbarHeight;
    final bool backwardsCompatibility = widget.backwardsCompatibility ?? appBarTheme.backwardsCompatibility ?? false;

    final Color backgroundColor = backwardsCompatibility
        ? widget.backgroundColor
        ?? appBarTheme.backgroundColor
        ?? theme.primaryColor
        : _resolveColor(
      states,
      widget.backgroundColor,
      appBarTheme.backgroundColor,
      colorScheme.brightness == Brightness.dark ? colorScheme.surface : colorScheme.primary,
    );

    final Color foregroundColor = widget.foregroundColor
        ?? appBarTheme.foregroundColor
        ?? (colorScheme.brightness == Brightness.dark ? colorScheme.onSurface : colorScheme.onPrimary);

    IconThemeData overallIconTheme = backwardsCompatibility
        ? widget.iconTheme
        ?? appBarTheme.iconTheme
        ?? theme.primaryIconTheme
        : widget.iconTheme
        ?? appBarTheme.iconTheme
        ?? theme.iconTheme.copyWith(color: foregroundColor);

    IconThemeData actionsIconTheme = widget.actionsIconTheme
        ?? appBarTheme.actionsIconTheme
        ?? overallIconTheme;

    TextStyle toolbarTextStyle = backwardsCompatibility
        ? widget.textTheme?.bodyText2
        ?? appBarTheme.textTheme?.bodyText2
        ?? theme.primaryTextTheme.bodyText2
        : widget.toolbarTextStyle
        ?? appBarTheme.toolbarTextStyle
        ?? theme.textTheme.bodyText2?.copyWith(color: foregroundColor);

    TextStyle titleTextStyle = backwardsCompatibility
        ? widget.textTheme?.headline6
        ?? appBarTheme.textTheme?.headline6
        ?? theme.primaryTextTheme.headline6
        : widget.titleTextStyle
        ?? appBarTheme.titleTextStyle
        ?? theme.textTheme.headline6?.copyWith(color: foregroundColor);

    if (widget.toolbarOpacity != 1.0) {
      final double opacity = const Interval(0.25, 1.0, curve: Curves.fastOutSlowIn).transform(widget.toolbarOpacity);
      if (titleTextStyle?.color != null)
        titleTextStyle = titleTextStyle.copyWith(color: titleTextStyle.color.withOpacity(opacity));
      if (toolbarTextStyle?.color != null)
        toolbarTextStyle = toolbarTextStyle.copyWith(color: toolbarTextStyle.color.withOpacity(opacity));
      overallIconTheme = overallIconTheme.copyWith(
        opacity: opacity * (overallIconTheme.opacity ?? 1.0),
      );
      actionsIconTheme = actionsIconTheme.copyWith(
        opacity: opacity * (actionsIconTheme.opacity ?? 1.0),
      );
    }

    Widget leading = widget.leading;
    if (leading == null && widget.automaticallyImplyLeading) {
      if (hasDrawer) {
        leading = IconButton(
          icon: const Icon(Icons.menu),
          iconSize: overallIconTheme.size ?? 24,
          onPressed: _handleDrawerButton,
          tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
        );
      } else {
        if (!hasEndDrawer && canPop)
          leading = useCloseButton ? const CloseButton() : const BackButton();
      }
    }
    if (leading != null) {
      leading = ConstrainedBox(
        constraints: BoxConstraints.tightFor(width: widget.leadingWidth ?? _kLeadingWidth),
        child: leading,
      );
    }

    Widget title = widget.title;
    if (title != null) {
      bool namesRoute;
      switch (theme.platform) {
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.linux:
        case TargetPlatform.windows:
          namesRoute = true;
          break;
        case TargetPlatform.iOS:
        case TargetPlatform.macOS:
          break;
      }

      title = _AppBarTitleBox(child: title);
      if (!widget.excludeHeaderSemantics) {
        title = Semantics(
          namesRoute: namesRoute,
          header: true,
          child: title,
        );
      }

      title = DefaultTextStyle(
        style: titleTextStyle,
        softWrap: false,
        overflow: TextOverflow.ellipsis,
        child: title,
      );

      // Set maximum text scale factor to [_kMaxTitleTextScaleFactor] for the
      // title to keep the visual hierarchy the same even with larger font
      // sizes. To opt out, wrap the [title] widget in a [MediaQuery] widget
      // with [MediaQueryData.textScaleFactor] set to
      // `MediaQuery.textScaleFactorOf(context)`.
      final MediaQueryData mediaQueryData = MediaQuery.of(context);
      title = MediaQuery(
        data: mediaQueryData.copyWith(
          textScaleFactor: math.min(
            mediaQueryData.textScaleFactor,
            _kMaxTitleTextScaleFactor,
          ),
        ),
        child: title,
      );
    }

    Widget actions;
    if (widget.actions != null && widget.actions.isNotEmpty) {
      actions = Row(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: widget.actions,
      );
    } else if (hasEndDrawer) {
      actions = IconButton(
        icon: const Icon(Icons.menu),
        iconSize: overallIconTheme.size ?? 24,
        onPressed: _handleDrawerButtonEnd,
        tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
      );
    }

    // Allow the trailing actions to have their own theme if necessary.
    if (actions != null) {
      actions = IconTheme.merge(
        data: actionsIconTheme,
        child: actions,
      );
    }

    final Widget toolbar = NavigationToolbar(
      leading: leading,
      middle: title,
      trailing: actions,
      centerMiddle: widget._getEffectiveCenterTitle(theme),
      middleSpacing: widget.titleSpacing ?? appBarTheme.titleSpacing ?? NavigationToolbar.kMiddleSpacing,
    );

    // If the toolbar is allocated less than toolbarHeight make it
    // appear to scroll upwards within its shrinking container.
    Widget appBar = ClipRect(
      child: CustomSingleChildLayout(
        delegate: _ToolbarContainerLayout(toolbarHeight),
        child: IconTheme.merge(
          data: overallIconTheme,
          child: DefaultTextStyle(
            style: toolbarTextStyle,
            child: toolbar,
          ),
        ),
      ),
    );
    if (widget.bottom != null) {
      appBar = Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Flexible(
            child: ConstrainedBox(
              constraints: BoxConstraints(maxHeight: toolbarHeight),
              child: appBar,
            ),
          ),
          if (widget.bottomOpacity == 1.0)
            widget.bottom
          else
            Opacity(
              opacity: const Interval(0.25, 1.0, curve: Curves.fastOutSlowIn).transform(widget.bottomOpacity),
              child: widget.bottom,
            ),
        ],
      );
    }

    // The padding applies to the toolbar and tabbar, not the flexible space.
    if (widget.primary) {
      appBar = SafeArea(
        bottom: false,
        top: true,
        child: appBar,
      );
    }

    appBar = Align(
      alignment: Alignment.topCenter,
      child: appBar,
    );

    if (widget.flexibleSpace != null) {
      appBar = Stack(
        fit: StackFit.passthrough,
        children: <Widget>[
          Semantics(
            sortKey: const OrdinalSortKey(1.0),
            explicitChildNodes: true,
            child: widget.flexibleSpace,
          ),
          Semantics(
            sortKey: const OrdinalSortKey(0.0),
            explicitChildNodes: true,
            // Creates a material widget to prevent the flexibleSpace from
            // obscuring the ink splashes produced by appBar children.
            child: Material(
              type: MaterialType.transparency,
              child: appBar,
            ),
          ),
        ],
      );
    }

    final SystemUiOverlayStyle overlayStyle = backwardsCompatibility
        ? _systemOverlayStyleForBrightness(
      widget.brightness
          ?? appBarTheme.brightness
          ?? theme.primaryColorBrightness,
    )
        : widget.systemOverlayStyle
        ?? appBarTheme.systemOverlayStyle
        ?? _systemOverlayStyleForBrightness(ThemeData.estimateBrightnessForColor(backgroundColor));

    return Semantics(
      container: true,
      child: AnnotatedRegion<SystemUiOverlayStyle>(
        // value: overlayStyle,
        // value: backgroundColor==Colors.white?SystemUiOverlayStyle.dark:SystemUiOverlayStyle.light,
        value: (widget.isBarStatusWhite??false)?SystemUiOverlayStyle.light:SystemUiOverlayStyle.dark,
        child: Material(
          color: backgroundColor,
          elevation: widget.elevation
              ?? appBarTheme.elevation
              ?? _defaultElevation,
          shadowColor: widget.shadowColor
              ?? appBarTheme.shadowColor
              ?? _defaultShadowColor,
          shape: widget.shape ?? appBarTheme.shape,
          child: Semantics(
            explicitChildNodes: true,
            child: appBar,
          ),
        ),
      ),
    );
  }
}

const double _kLeadingWidth = kToolbarHeight; // So the leading button is square.
const double _kMaxTitleTextScaleFactor = 1.34;
class _PreferredAppBarSize extends Size {
  _PreferredAppBarSize(this.toolbarHeight, this.bottomHeight)
      : super.fromHeight((toolbarHeight ?? kToolbarHeight) + (bottomHeight ?? 0));

  final double toolbarHeight;
  final double bottomHeight;
}
class _AppBarTitleBox extends SingleChildRenderObjectWidget {
  const _AppBarTitleBox({ Key key, Widget child }) : assert(child != null), super(key: key, child: child);

  @override
  _RenderAppBarTitleBox createRenderObject(BuildContext context) {
    return _RenderAppBarTitleBox(
      textDirection: Directionality.of(context),
    );
  }

  @override
  void updateRenderObject(BuildContext context, _RenderAppBarTitleBox renderObject) {
    renderObject.textDirection = Directionality.of(context);
  }
}
class _RenderAppBarTitleBox extends RenderAligningShiftedBox {
  _RenderAppBarTitleBox({
    RenderBox child,
    TextDirection textDirection,
  }) : super(child: child, alignment: Alignment.center, textDirection: textDirection);

  @override
  Size computeDryLayout(BoxConstraints constraints) {
    final BoxConstraints innerConstraints = constraints.copyWith(maxHeight: double.infinity);
    final Size childSize = child.getDryLayout(innerConstraints);
    return constraints.constrain(childSize);
  }

  @override
  void performLayout() {
    final BoxConstraints innerConstraints = constraints.copyWith(maxHeight: double.infinity);
    child.layout(innerConstraints, parentUsesSize: true);
    size = constraints.constrain(child.size);
    alignChild();
  }
}
class _ToolbarContainerLayout extends SingleChildLayoutDelegate {
  const _ToolbarContainerLayout(this.toolbarHeight);

  final double toolbarHeight;

  @override
  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
    return constraints.tighten(height: toolbarHeight);
  }

  @override
  Size getSize(BoxConstraints constraints) {
    return Size(constraints.maxWidth, toolbarHeight);
  }

  @override
  Offset getPositionForChild(Size size, Size childSize) {
    return Offset(0.0, size.height - childSize.height);
  }

  @override
  bool shouldRelayout(_ToolbarContainerLayout oldDelegate) =>
      toolbarHeight != oldDelegate.toolbarHeight;
}

